home *** CD-ROM | disk | FTP | other *** search
- /* Automatic SLIP/PPP line dialer.
- *
- * Copyright 1991 Phil Karn, KA9Q
- *
- * Mar '91 Bill Simpson & Glenn McGregor
- * completely re-written;
- * human readable control file;
- * includes wait for string, and speed sense;
- * dials immediately when invoked.
- * May '91 Bill Simpson
- * re-ordered command line;
- * allow dial only;
- * allow inactivity timeout without ping.
- * Sep '91 Bill Simpson
- * Check known DTR & RSLD state for redial decision
- * 11 Mar 92 Giles Todd
- * Add "configure:" and "execute:" sections and new commands.
- * 19 Mar 92 Giles Todd
- * Fix failure string processing.
- * 31 May 92 Giles Todd
- * Fix empty configure string problems.
- * 02 Jun 92 Giles Todd
- * Fix dial session cancel bug.
- *
- $Id: dialer.c 1.13 94/01/04 14:09:02 ROOT_DOS Exp $
- *
- * 04 Aug 92 1.6 GT No change.
- * 09 Aug 92 1.7 GT Inline dialing.
- * 17 Aug 92 1.8 GT Allow escape from inline dial.
- * 13 Sep 92 1.9 CMS Ignore script lines consisting only of a newline.
- * 03 Apr 93 1.11 GT Fix order of calls.
- * 08 May 93 1.12 GT Fix warnings.
- * Improve dialer interruption.
- * 10 Dec 93 1.13 GT Don't obscure modem messages.
- *
- * ATARI version by David Nash - dnash@chaos.demon.co.uk
- *
- * Include st_asy.h in place of 8250.h
- *
- * 04.11.94 DFN dodial_status correct call to iostatus function
- *
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- #include "global.h"
- #include "config.h"
- #include "mbuf.h"
- #include "timer.h"
- #include "proc.h"
- #include "iface.h"
- #include "netuser.h"
- #ifdef ATARI
- #include "st_asy.h"
- #else
- #include "8250.h"
- #endif
- #include "asy.h"
- #include "tty.h"
- #include "session.h"
- #include "socket.h"
- #include "cmdparse.h"
- #include "devparam.h"
- #include "icmp.h"
- #include "files.h"
- #include "main.h"
- #include "trace.h"
- #include "hardware.h"
- #include "commands.h"
-
- extern struct cmds far Cmds[];
-
- #define MIN_INTERVAL 5L
-
- typedef struct item ITEM;
-
- struct item
- {
- char *data; /* some text */
- ITEM *next; /* -> next in list */
- };
-
-
- static int redial __ARGS((struct iface *ifp, char *file));
-
- static int cfg_init __ARGS((int argc, char *argv[], void *p));
- static int cfg_dial_cmd __ARGS((int argc, char *argv[], void *p));
- static int cfg_ld_code __ARGS((int argc, char *argv[], void *p));
- static int cfg_number __ARGS((int argc, char *argv[], void *p));
- static int cfg_retries __ARGS((int argc, char *argv[], void *p));
-
- static int dodial_control __ARGS((int argc, char *argv[], void *p));
- static int dodial_dial __ARGS((int argc, char *argv[], void *p));
- static int dodial_init __ARGS((int argc, char *argv[], void *p));
- static int dodial_send __ARGS((int argc, char *argv[], void *p));
- static int dodial_speed __ARGS((int argc, char *argv[], void *p));
- static int dodial_status __ARGS((int argc, char *argv[], void *p));
- static int dodial_wait __ARGS((int argc, char *argv[], void *p));
- static int dodial_cwait __ARGS((int argc, char *argv[], void *p));
-
- static int __stdargs dodialer __ARGS((int argc, char *argv[], void *p));
- static int __stdargs do_inline __ARGS((int argc, char *argv[], void *p));
-
- static void add_cmd __ARGS((ITEM **hdr, ITEM **ptr, char *buf));
- static char *next_cmd __ARGS((char *buf, ITEM **ptr));
- static void clean_up __ARGS((void));
- static void clean __ARGS((ITEM **hdr));
- static int internal_send __ARGS((char *ptr, void *p));
- static int asy_kb_poll __ARGS((int dev));
-
- static struct cmds dial_cmds[] =
- {
- { "control", dodial_control, 0, 2, "control up | down" },
- { "dial", dodial_dial, 0, 0, "dial" },
- { "init", dodial_init, 0, 0, "init" },
- { "send", dodial_send, 0, 2,
- "send \"string\" [<milliseconds>]" },
- { "speed", dodial_speed, 0, 2, "speed <bps>" },
- { "status", dodial_status, 0, 2, "status up | down" },
- { "wait", dodial_wait, 0, 2,
- "wait <milliseconds> [ \"string\" [speed] ]" },
- { "cwait", dodial_cwait, 0, 2,
- "cwait <milliseconds> [ \"success string\" \"failure string\" [, \"failure string\" ...] [speed] ]" },
- { NULLCHAR, NULLFP, 0, 0, "Unknown command" },
- };
-
- static struct cmds cfg_cmds[] =
- {
- { "init", cfg_init, 0, 2, "init \"string\"" },
- { "dial_cmd", cfg_dial_cmd, 0, 2, "dial_cmd \"string\"" },
- { "ld_code", cfg_ld_code, 0, 2, "ld_code \"string\"" },
- { "number", cfg_number, 0, 2, "number \"string\"" },
- { "retries", cfg_retries, 0, 2, "retries <count>" },
- { NULLCHAR, NULLFP, 0, 0, "Unknown command" },
- };
-
- static char cfg_intro[] = "configure:";
- static char exe_intro[] = "execute:";
- static int configuring = 0; /* nz - found configuration section */
-
- static char *init = NULL; /* initialization string */
- static char *dial_cmd = NULL; /* modem dial command */
- static char *ld_code = NULL; /* long distance code */
- static ITEM *number = NULL; /* telephone numbers */
- static ITEM *nr_ptr = NULL; /* -> current number */
- static unsigned retries = 1; /* number of dial retries */
- static ITEM *cfg_cmd = NULL; /* configuration commands */
- static ITEM *exe_cmd = NULL; /* script commands */
- static ITEM *cmd_ptr = NULL; /* -> current script command */
-
- static int dial_inline = 0; /* nz - dial inline */
- static int interrupted; /* nz - dial interrupted */
-
-
- /****************************************************************************
- * do_inline *
- * Toggles the "inline dialing" flag and sets and resets the dialer task's *
- * stack size. *
- ****************************************************************************/
-
- #ifndef ATARI
- #define DIALER_STACK 512
- #else
- #define DIALER_STACK 2512
- #endif
-
- int __stdargs do_inline (argc, argv, p)
- int argc;
- char *argv[];
- void *p;
- {
- int rc; /* return value */
- struct cmds *cmd_ptr; /* -> command structure */
-
- /* Set / reset / report flag value. */
-
- rc = setbool (&dial_inline, "Inline dialing", argc, argv);
-
- /* Set the dialer stack size. */
-
- cmd_ptr = Cmds;
- while (cmd_ptr->name != NULLCHAR)
- {
- if (strcmp (cmd_ptr->name, "dialer") == 0)
- break;
-
- cmd_ptr++;
- }
-
- if (dial_inline == 0)
- cmd_ptr->stksize = DIALER_STACK; /* asynch process */
- else
- cmd_ptr->stksize = 0; /* inline process */
-
- return (rc);
- } /* int do_inline (argc, argv, p) */
-
-
- /* dial <iface> <filename> [ <seconds> [ <pings> [<hostid>] ] ]
- * <iface> must be asy type
- * <filename> contains commands which are executed.
- * missing: kill outstanding dialer.
- * <seconds> interval to check for activity on <iface>.
- * (if 0 then demand dial)
- * <pings> number of missed pings before redial.
- * <hostid> interface to ping.
- */
-
- int __stdargs dodialer (argc, argv, p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp;
- struct asy *ap;
- int32 interval = 0L; /* in seconds */
- int32 last_wait = 0L;
- int32 target = 0L;
- int pings = 0;
- int countdown;
- char *filename;
- char *ifn;
- int result;
- int s;
- int exit_on_fail;
-
- if ((ifp = if_lookup (argv[1])) == NULLIF)
- {
- tprintf ("Interface %s unknown\n", argv[1]);
- return 1;
- }
-
- if (ifp->dev >= ASY_MAX || Asy[ifp->dev].iface != ifp)
- {
- tprintf ("Interface %s not asy port\n", argv[1]);
- return 1;
- }
-
- if (ifp->supv != NULLPROC)
- {
- while (ifp->supv != NULLPROC)
- {
- alert (ifp->supv, EABORT);
- pwait (NULL);
- }
-
- tprintf ("dialer terminated on %s\n", argv[1]);
- }
-
- if (argc < 3)
- {
- /* just terminating */
- return 0;
- }
-
- chname (Curproc, ifn = if_name (ifp, " dialer"));
- free (ifn);
- #ifdef ATARI
- if (!access(argv[2], 0)) /* check if file exists */
- filename = argv[2];
- else
- #endif
- filename = rootdircat (argv[2]);
-
- ap = &Asy[ ifp->dev ];
-
- if (argc == 4 && strcmp(argv[3], "failexit") == 0)
- exit_on_fail = 1;
- else exit_on_fail = 0;
-
- /* handle minimal command (just thru filename) */
-
- if (argc < 4 || exit_on_fail)
- {
- /* just dialing */
- ifp->supv = Curproc; /* so that it can be cancelled */
- result = redial (ifp, filename);
-
- if (filename != argv[2])
- free (filename);
-
- ifp->supv = NULLPROC;
-
- if (result != 0 && exit_on_fail == 1)
- doexit (0, NULL, NULL);
-
- return result;
- }
- /* get polling interval (arg 3) */
- else if (strcmp(argv[3], "demand")
- && (interval = atol (argv[3])) <= MIN_INTERVAL)
- {
- tprintf ("interval must be > %d seconds\n", MIN_INTERVAL);
- return 1;
- }
-
- if (strcmp(argv[3], "demand") == 0)
- /* Interval of 0, so we're demand dialing */
- {
- int32 backoff;
- tprintf("Demand dialing enabled\n");
- backoff = 4;
- ifp->supv = Curproc; /* so that it can be cancelled */
- ifp->dial_me = 0;
- while (!main_exit)
- {
- alarm (2000L);
- if (pwait (& (ifp->supv)) == EABORT)
- break;
- alarm (0L);
- if (ifp->dial_me)
- {
- if (ap->dtr_usage == FOUND_DOWN ||
- ap->dtr_usage == MOVED_DOWN ||
- ap->rlsd_line_control == MOVED_DOWN)
- /* dial has been requested _and_ the link is down */
- {
- tprintf("About to dial\n");
- if (redial (ifp, filename) == 0) {
- tprintf("Dial succeeded\n");
- backoff = 4;
- }
- else {
- if (backoff < 90000L) /* Max backoff is day & a bit */
- backoff = backoff * 2;
- tprintf("Dial failed, backing off for %lu seconds\n",
- backoff);
- }
- }
- alarm (backoff * 1000L);
- if (pwait (& (ifp->supv)) == EABORT)
- break;
- alarm (0L);
- ifp->dial_me = 0;
- }
- }
- ifp->supv = NULLPROC;
- tprintf("Demand dialing finished\n");
- return 0;
- }
-
- /* get the number of pings before redialing (arg 4) */
-
- if (argc < 5)
- {
- }
- else if ((pings = atoi (argv[4])) <= 0)
- {
- tprintf ("pings must be > 0\n");
- return 1;
- }
-
- /* retrieve the host name (arg 5) */
-
- if (argc < 6)
- {
- }
- else if ((target = resolve (argv[5])) == 0L)
- {
- tprintf (Badhost, argv[5]);
- return 1;
- }
-
- countdown = pings;
- ifp->supv = Curproc;
-
- while (!main_exit)
- {
- int32 wait_for = interval;
-
- if (ap->dtr_usage == FOUND_DOWN ||
- ap->dtr_usage == MOVED_DOWN ||
- ap->rlsd_line_control == MOVED_DOWN)
- {
- /* definitely down */
-
- if (redial (ifp, filename) < 0)
- break;
-
- }
- else if (ifp->lastrecv >= last_wait)
- {
- /* got something recently */
-
- wait_for -= secclock () - ifp->lastrecv;
- countdown = pings;
- }
- else if (countdown < 1)
- {
- /* we're down, or host we ping is down */
-
- if (redial (ifp, filename) < 0)
- break;
-
- countdown = pings;
- }
- else if (target != 0L &&
- (s = socket (AF_INET, SOCK_RAW, ICMP_PTCL)) != -1)
- {
- pingem (s, target, 0, (int16)s, 0);
- close_s (s);
- countdown--;
- }
- else if (ifp->echo != NULLFP)
- {
- (*ifp->echo) (ifp, NULLBUF);
- countdown--;
- }
-
- last_wait = secclock ();
- if (wait_for != 0L)
- {
- alarm (wait_for * 1000L);
- if (pwait (& (ifp->supv)) == EABORT)
- break;
-
- alarm (0L); /* clear alarm */
- }
-
- } /* while (!main_exit) */
-
- if (filename != argv[2])
- free (filename);
-
- ifp->supv = NULLPROC; /* We're being terminated */
- return 0;
- } /* int dodialer (argc, argv, p) */
-
-
- /* execute dialer commands
- * returns: -1 fatal error, 0 OK, 1 try again
- */
-
- static int redial (ifp, file)
- struct iface *ifp;
- char *file;
- {
- char *inbuf, *intmp;
- FILE *fp;
- int (*rawsave) __ARGS ((struct iface *, struct mbuf *));
- struct session *sp;
- int result = 0;
- int save_input = Curproc->input;
- int save_output = Curproc->output;
- unsigned i; /* loop counter */
-
- if ((fp = fopen (file, READ_TEXT)) == NULLFILE)
- {
- tprintf ("redial: can't read %s\n", file);
- return -1; /* Causes dialer proc to terminate */
- }
-
- /* Save output handler and temporarily redirect output to null */
-
- if (ifp->raw == bitbucket)
- {
- tprintf ("redial: tip or dialer already active on %s\n", ifp->name);
- (void) fclose (fp);
- return -1;
- }
-
- /* allocate a session descriptor */
-
- if (dial_inline == 0)
- {
- if ((sp = newsession (ifp->name, DIAL)) == NULLSESSION)
- {
- tprintf ("Too many sessions\n");
- (void) fclose (fp);
- return 1;
- }
-
- }
-
- tprintf ("Dialing on %s\n\n", ifp->name);
-
- /* Save output handler and temporarily redirect output to null */
-
- rawsave = ifp->raw;
- ifp->raw = bitbucket;
-
- /* Suspend the packet input driver. Note that the transmit driver
- * is left running since we use it to send buffers to the line.
- */
-
- suspend (ifp->rxproc);
-
- #ifdef notdef
- tprintf ("rlsd: 0x%02x, dtr: 0x%02x\n",
- Asy[ifp->dev].rlsd_line_control,
- Asy[ifp->dev].dtr_usage);
- #endif
-
- inbuf = mallocw (BUFSIZ);
-
- /* Read the file into cfg_cmd and exe_cmd. */
-
- cfg_cmd = NULL;
- exe_cmd = NULL;
- cmd_ptr = cfg_cmd; /* initialize list pointer */
- configuring = 0; /* not configuring yet */
- while (fgets (inbuf, BUFSIZ, fp) != NULLCHAR)
- {
- if (strnicmp (inbuf, cfg_intro, strlen (cfg_intro)) == 0)
- {
- configuring = 1; /* found config section */
- break;
- }
-
- }
-
- if (configuring == 0)
- {
- tprintf ("redial: no \"configure:\" section\n");
- (void) fclose (fp);
- free (inbuf);
- ifp->raw = rawsave;
- resume (ifp->rxproc);
- tprintf ("\nDial %s complete\n", ifp->name);
-
- /* Wait for awhile, so the user can read the screen. */
- #ifndef ATARI
- Pause (10000L);
- #endif
- if (dial_inline == 0)
- {
- freesession (sp);
- }
-
- Curproc->input = save_input;
- Curproc->output = save_output;
- return (-1);
- }
-
- while (fgets (inbuf, BUFSIZ, fp) != NULLCHAR)
- {
- if (strnicmp (inbuf, exe_intro, strlen (exe_intro)) == 0)
- {
- configuring = 0; /* found execute section */
- break;
- }
-
- if (*inbuf != '#' && *inbuf != '\n')
- add_cmd (&cfg_cmd, &cmd_ptr, inbuf); /* add to list */
-
- }
-
- if (configuring == 1)
- {
- tprintf ("redial: no \"execute:\" section\n");
- clean_up (); /* free list */
- (void) fclose (fp);
- free (inbuf);
- ifp->raw = rawsave;
- resume (ifp->rxproc);
- tprintf ("\nDial %s complete\n", ifp->name);
-
- /* Wait for awhile, so the user can read the screen. */
- #ifndef ATARI
- Pause (10000L);
- #endif
- if (dial_inline == 0)
- {
- freesession (sp);
- }
-
- Curproc->input = save_input;
- Curproc->output = save_output;
- return (-1);
- }
-
- cmd_ptr = exe_cmd; /* read in execute commands */
- while (fgets (inbuf, BUFSIZ, fp) != NULLCHAR)
- {
- if (*inbuf != '#' && *inbuf != '\n')
- add_cmd (&exe_cmd, &cmd_ptr, inbuf); /* add to list */
-
- }
-
- (void) fclose (fp);
- intmp = mallocw (BUFSIZ);
-
- /* Do the configure commands. */
-
- cmd_ptr = cfg_cmd;
- while (next_cmd (inbuf, &cmd_ptr) != NULLCHAR)
- {
- strcpy (intmp, inbuf);
- rip (intmp);
- log (-1, "%s dialer: %s", ifp->name, intmp);
- if ((result = cmdparse (cfg_cmds, inbuf, ifp)) != 0)
- {
- tprintf ("\ninput line: %s\n", intmp);
- break;
- }
-
- } /* while (next_cmd (inbuf, &cmd_ptr) != NULLCHAR) */
-
- /* Do the execute commands. */
-
- nr_ptr = number; /* initialize number pointer */
- if (result == 0)
- {
- interrupted = 0;
- for (i = 0; i < retries; i++)
- {
- if (pwait (NULL) == EABORT)
- break; /* we are being killed */
-
- cmd_ptr = exe_cmd;
- while (next_cmd (inbuf, &cmd_ptr) != NULLCHAR)
- {
- int c; /* input character */
-
- /* Poll the keyboard for 1/10 of a second to
- * see if <ESC> has been pressed.
- */
-
- if (dial_inline != 0)
- {
- alarm (100L);
- if ((c = recvchar (Curproc->input)) != EOF)
- {
- alarm (0L);
- recv_mbuf(Curproc->input,NULLBUFP,0,NULLCHAR,0);
- if (c == 0x01b)
- {
- /* <ESC> pressed - give up. */
-
- interrupted = 1;
- result = -1;
- tprintf ("interrupted\n");
- break;
- }
-
- }
-
- alarm (0L);
- } /* if (dial_inline != 0) */
-
- /* Process script command. */
-
- strcpy (intmp, inbuf);
- rip (intmp);
- log (-1, "%s dialer: %s", ifp->name, intmp);
- if ((result = cmdparse (dial_cmds, inbuf, ifp)) != 0)
- {
- tprintf ("\ninput line: %s\n", intmp);
- break;
- }
-
- } /* while (next_cmd (inbuf, &cmd_ptr) != NULLCHAR) */
-
- if (result == 0 || interrupted != 0)
- break; /* dial succeeded */
-
- } /* for (i = 0; i < retries; i++) */
-
- } /* if (result == 0) */
-
- clean_up (); /* free lists */
- free (inbuf);
- free (intmp);
-
- if (result == 0)
- {
- ifp->lastsent = ifp->lastrecv = secclock ();
- }
-
- ifp->raw = rawsave;
- resume (ifp->rxproc);
- tprintf ("\nDial %s complete\n", ifp->name);
-
- /* Wait for awhile, so the user can read the screen,
- * AND to give it time to send some packets on the new connection!
- */
- #ifndef ATARI
- Pause (10000L);
- #endif
- if (dial_inline == 0)
- {
- freesession (sp);
- }
-
- Curproc->input = save_input;
- Curproc->output = save_output;
- return result;
- } /* static int redial (ifp, file) */
-
-
- static int dodial_control (argc, argv, p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp = p;
- int param;
-
- if (ifp->ioctl == NULL)
- return -1;
-
- if ((param = devparam (argv[1])) == -1)
- return -1;
-
- (*ifp->ioctl) (ifp, param, TRUE, atol (argv[2]));
- return 0;
- } /* static int dodial_control (argc, argv, p) */
-
-
- static int dodial_send (argc, argv, p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp = p;
- struct mbuf *bp;
-
- if (argc > 2)
- {
- /* Send characters with inter-character delay
- * (for dealing with prehistoric Micom switches that
- * can't take back-to-back characters...yes, they
- * still exist.)
- */
-
- char *cp;
- int32 cdelay = atol (argv[2]);
-
- for (cp = argv[1];*cp != '\0';cp++)
- {
- bp = qdata (cp, 1);
- asy_send (ifp->dev, bp);
- Pause (cdelay);
- }
-
- }
- else
- {
- bp = qdata (argv[1], strlen (argv[1]));
- if (ifp->trace & IF_TRACE_RAW)
- raw_dump (ifp, IF_TRACE_OUT, bp);
-
- asy_send (ifp->dev, bp);
- }
-
- return 0;
- } /* static int dodial_send (argc, argv, p) */
-
-
- static int dodial_speed (argc, argv, p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp = p;
-
- if (argc < 2)
- {
- tprintf ("current speed = %u bps\n", Asy[ifp->dev].speed);
- return 0;
- }
-
- return asy_speed (ifp->dev, (int16) atol (argv[1]));
- } /* static int dodial_speed (argc, argv, p) */
-
-
- /*
- dodial_status - Bring interface up or down
- */
-
- static int dodial_status (int argc, char *argv[], void *p)
- {
- struct iface *ifp = p;
- int param;
-
- if (ifp->iostatus == NULL)
- return -1;
-
- if ((param = devparam (argv[1])) == -1)
- return -1;
-
- /* (*ifp->iostatus) (ifp, param, atol (argv[2])); produces crash? */
-
- (*ifp->iostatus) (ifp, param, 0);
-
- return 0;
- }
-
-
- static int dodial_wait (argc, argv, p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp = p;
- register int c = -1;
-
- alarm (atol (argv[1]));
-
- if (argc == 2)
- {
- while ((c = asy_kb_poll (ifp->dev)) != -1)
- {
- tputc (c &= 0x7F);
- tflush ();
- }
-
- alarm (0L);
- return 0;
- }
- else
- {
- register char *cp = argv[2];
-
- while (*cp != '\0' && (c = asy_kb_poll (ifp->dev)) != -1)
- {
- tputc (c &= 0x7F);
- tflush ();
-
- if (*cp++ != c)
- {
- cp = argv[2];
- }
-
- } /* while (*cp != '\0' && (c = asy_kb_poll (ifp->dev)) != -1) */
-
- if (argc > 3)
- {
- if (stricmp (argv[3], "speed") == 0)
- {
- int16 speed = 0;
-
- while ((c = asy_kb_poll (ifp->dev)) != -1)
- {
- tputc (c &= 0x7F);
- tflush ();
-
- if (isdigit (c))
- {
- speed *= 10;
- speed += c - '0';
- }
- else
- {
- alarm (0L);
- return asy_speed (ifp->dev, speed);
- }
-
- } /* while ((c = asy_kb_poll (ifp->dev)) != -1) */
-
- } /* if (stricmp (argv[3], "speed") == 0) */
- else
- {
- return -1;
- }
-
- } /* if (argc > 3) */
-
- } /* if (argc != 2) */
-
- alarm (0L);
- return (c == -1);
- } /* static int dodial_wait (argc, argv, p) */
-
-
- /****************************************************************************
- * cfg_init *
- * Sets up the modem initialization string. *
- ****************************************************************************/
-
- static int cfg_init (argc, argv, p)
- int argc;
- char **argv;
- void *p;
- {
- if (init != NULL)
- free (init);
-
- if (strlen (argv[1]) == 0)
- {
- init = NULL;
- return (0);
- }
-
- init = mallocw (strlen (argv[1]) + 1);
- (void) strcpy (init, argv[1]);
- return (0);
- } /* static int cfg_init (argc, argv, p) */
-
-
- /****************************************************************************
- * cfg_dial_cmd *
- * Sets up the modem dial command. *
- ****************************************************************************/
-
- static int cfg_dial_cmd (argc, argv, p)
- int argc;
- char **argv;
- void *p;
- {
- if (dial_cmd != NULL)
- free (dial_cmd);
-
- if (strlen (argv[1]) == 0)
- {
- dial_cmd = NULL;
- return (0);
- }
-
- dial_cmd = mallocw (strlen (argv[1]) + 1);
- (void) strcpy (dial_cmd, argv[1]);
- return (0);
- } /* static int cfg_dial_cmd (argc, argv, p) */
-
-
- /****************************************************************************
- * cfg_ld_code *
- * Sets up the long distance code. *
- ****************************************************************************/
-
- static int cfg_ld_code (argc, argv, p)
- int argc;
- char **argv;
- void *p;
- {
- if (ld_code != NULL)
- free (ld_code);
-
- if (strlen (argv[1]) == 0)
- {
- ld_code = NULL;
- return (0);
- }
-
- ld_code = mallocw (strlen (argv[1]) + 1);
- (void) strcpy (ld_code, argv[1]);
- return (0);
- } /* static int cfg_ld_code (argc, argv, p) */
-
-
- /****************************************************************************
- * cfg_retries *
- * Sets up the number of dial retries. *
- ****************************************************************************/
-
- static int cfg_retries (argc, argv, p)
- int argc;
- char **argv;
- void *p;
- {
- (void) sscanf (argv[1], "%u", &retries);
- if (retries <= 0)
- return (-1); /* must be >= 1 */
-
- return (0);
- } /* static int cfg_retries (argc, argv, p) */
-
-
- /****************************************************************************
- * cfg_number *
- * Adds a number to the dial list. *
- ****************************************************************************/
-
- static int cfg_number (argc, argv, p)
- int argc;
- char **argv;
- void *p;
- {
- add_cmd (&number, &nr_ptr, argv[1]);
- return (0);
- } /* static int cfg_number (argc, argv, p) */
-
-
- /****************************************************************************
- * internal_send *
- * Sends a string to dodial_send (). *
- ****************************************************************************/
-
- static int internal_send (ptr, p)
- char *ptr;
- void *p;
- {
- char *argv[2];
-
- argv[0] = NULL;
- argv[1] = ptr;
- return (dodial_send (2, argv, p));
- } /* static int internal_send (ptr, p) */
-
-
- /****************************************************************************
- * dodial_init *
- * Send the initialisation string to the modem. *
- ****************************************************************************/
-
- static int dodial_init (argc, argv, p)
- int argc;
- char **argv;
- void *p;
- {
- if (init == NULL)
- return (0); /* no initialization string - ok */
-
- return (internal_send (init, p));
- } /* static int dodial_init (argc, argv, p) */
-
-
- /****************************************************************************
- * dodial_dial *
- * Send the dialer commands and the next number to the modem. *
- ****************************************************************************/
-
- static int dodial_dial (argc, argv, p)
- int argc;
- char **argv;
- void *p;
- {
- char *buf; /* -> number buffer */
- int rc; /* result code */
-
- if (number == NULL)
- return (-1); /* no numbers specified */
-
- buf = mallocw (BUFSIZ); /* get a buffer for the number */
- if (dial_cmd != NULL)
- {
- /* Send the dial command. */
-
- if ((rc = internal_send (dial_cmd, p)) != 0)
- {
- free (buf);
- return (rc);
- }
-
- } /* if (dial_cmd != NULL) */
-
- if (ld_code != NULL)
- {
- /* Send the long distance code. */
-
- if ((rc = internal_send (ld_code, p)) != 0)
- {
- free (buf);
- return (rc);
- }
-
- } /* if (ld_code != NULL) */
-
- /* Send the next number. */
-
- if (next_cmd (buf, &nr_ptr) == NULLCHAR)
- {
- /* Try resetting the pointer. */
-
- nr_ptr = number;
- if (next_cmd (buf, &nr_ptr) == NULLCHAR)
- {
- free (buf); /* gone badly wrong */
- return (-1);
- }
-
- } /* if (next_cmd (buf, nr_ptr) == NULLCHAR) */
-
- if ((rc = internal_send (buf, p)) != 0) /* send the number */
- {
- free (buf);
- return (rc);
- }
-
- rc = internal_send ("\r", p);
- free (buf);
- return (rc);
- } /* static int dodial_dial (argc, argv, p) */
-
-
- /****************************************************************************
- * dodial_cwait *
- * Conditional version of dodial_wait (). *
- ****************************************************************************/
-
- static int dodial_cwait (argc, argv, p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *ifp = p;
- register int c = -1;
- int speedarg; /* index of "speed" argument */
- int lastarg; /* index of last argument */
- int i; /* loop counter */
- char failed; /* failure flag - nz means failed */
-
- alarm (atol (argv[1]));
-
- lastarg = argc - 1;
- if (stricmp (argv[lastarg], "speed") == 0)
- {
- speedarg = lastarg;
- lastarg--;
- }
- else
- speedarg = 0; /* no "speed" argument */
-
- if (argc == 2)
- {
- /* Wait for duration expiry only. */
-
- while ((c = asy_kb_poll (ifp->dev)) != -1)
- {
- tputc (c &= 0x7F);
- tflush ();
- }
-
- alarm (0L);
- return 0;
- }
- else
- {
- register char *cp = argv[2]; /* -> success string */
- char **fail_ptr; /* array of ptrs to failure strings */
-
- /* Set up the array of failure string pointers. */
-
- fail_ptr = (char **) mallocw ((lastarg - 2) * sizeof (char *));
- for (i = 0; i < (lastarg - 2); i++)
- fail_ptr[i] = argv[i + 3];
-
- /* Looking for string matches. */
-
- failed = 0;
- while ((c = asy_kb_poll (ifp->dev)) != -1)
- {
- tputc (c &= 0x7F);
- tflush ();
-
- /* Check the success string first. */
-
- if (*cp == '\0')
- break; /* we got a connect */
-
- if (*cp++ != c)
- {
- cp = argv[2];
- }
-
- /* Now check the failure strings. */
-
- for (i = 0; i < (lastarg - 2); i++)
- {
- if (*fail_ptr[i] == '\0')
- {
- failed = 1;
- break; /* we lost */
- }
-
- if (*fail_ptr[i]++ != c)
- {
- fail_ptr[i] = argv[i + 3];
- }
-
- }
-
- if (failed)
- break;
-
- } /* while ((c = asy_kb_poll (ifp->dev)) != -1) */
-
- free (fail_ptr); /* give back heap memory */
-
- /* If we get here, we may have matched the "success" string. */
-
- if (*cp != '\0')
- {
- alarm (0L);
- return (-1); /* we didn't */
- }
-
- if (speedarg != 0)
- {
- int16 speed = 0;
-
- while ((c = asy_kb_poll (ifp->dev)) != -1)
- {
- tputc (c &= 0x7F);
- tflush ();
-
- if (isdigit (c))
- {
- speed *= 10;
- speed += c - '0';
- }
- else
- {
- alarm (0L);
- return asy_speed (ifp->dev, speed);
- }
-
- } /* while ((c = asy_kb_poll (ifp->dev)) != -1) */
-
- } /* if (stricmp (lastarg, "speed") == 0) */
-
- } /* if (argc != 2) */
-
- alarm (0L);
- return (c == -1);
- } /* static int dodial_cwait (argc, argv, p) */
-
-
- /****************************************************************************
- * add_cmd *
- * Add a string to the end of the list whose header is pointed to by *
- * <*hdr>. <*ptr> (if non-NULL) points to the last item in the list. *
- * <buf> points to the data to be added to the list and is assumed to be *
- * an ASCIIZ string. *
- ****************************************************************************/
-
- static void add_cmd (hdr, ptr, buf)
- ITEM **hdr;
- ITEM **ptr;
- char *buf;
- {
- if (strlen (buf) == 0)
- return;
-
- if (*hdr == NULL)
- {
- /* Empty list. */
-
- *hdr = (ITEM *) mallocw (sizeof (ITEM));
- *ptr = *hdr;
- }
- else
- {
- (*ptr)->next = (ITEM *) mallocw (sizeof (ITEM));
- *ptr = (*ptr)->next;
- }
-
- (*ptr)->data = (char *) mallocw (strlen (buf) + 1);
- (*ptr)->next = NULL;
- (void) strcpy ((*ptr)->data, buf);
- } /* static void add_cmd (hdr, ptr, buf) */
-
-
- /****************************************************************************
- * next_cmd *
- * Copies the data part of the item pointed to by <*ptr> into the buffer *
- * pointed to by <buf>. This area is assumed to be large enough to hold *
- * the data. <*ptr> is advanced to point to the next item. Returns <buf> *
- * if there is another item, NULLCHAR at the end of the list. *
- ****************************************************************************/
-
- static char *next_cmd (buf, ptr)
- char *buf;
- ITEM **ptr;
- {
- if (*ptr == NULL)
- return (NULLCHAR);
-
- (void) strcpy (buf, (*ptr)->data);
- *ptr = (*ptr)->next;
- return (buf);
- } /* static char *next_cmd (buf, ptr) */
-
-
- /****************************************************************************
- * clean_up *
- * Frees the heap memory used by the various lists. *
- ****************************************************************************/
-
- static void clean_up ()
- {
- clean (&number);
- clean (&cfg_cmd);
- clean (&exe_cmd);
- if (init != NULL)
- {
- free (init);
- init = NULL;
- }
-
- if (dial_cmd != NULL)
- {
- free (dial_cmd);
- dial_cmd = NULL;
- }
-
- if (ld_code != NULL)
- {
- free (ld_code);
- ld_code = NULL;
- }
-
- retries = 1;
- } /* static void clean_up () */
-
-
- /****************************************************************************
- * clean *
- * Free up the list pointed to by <*hdr>. *
- ****************************************************************************/
-
- static void clean (hdr)
- ITEM **hdr;
- {
- ITEM *p, *q; /* list followers */
-
- p = *hdr;
- while (p != NULL)
- {
- q = p->next;
- free (p->data);
- free (p);
- p = q;
- }
-
- *hdr = NULL;
- } /* static void clean (hdr) */
-
-
- /****************************************************************************
- * asy_kb_poll *
- * Polls the async interface for incoming characters and the keyboard for *
- * <ESC>. Returns the character on the async receive queue or -1 if timed *
- * out or <ESC> detected. *
- ****************************************************************************/
-
- static int asy_kb_poll (dev)
- int dev;
- {
- int c; /* input character */
-
- for (;;)
- {
- /* Check keyboard. */
-
- if (socklen (Curproc->input,0) > 0)
- {
- c = recvchar (Curproc->input);
- if (c != EOF)
- {
- recv_mbuf (Curproc->input, NULLBUFP, 0, NULLCHAR, 0);
- if (c == 0x1b)
- {
- /* <ESC> pressed - give up. */
-
- interrupted = 1;
- c = -1;
- break;
- }
-
- } /* if (c != EOF) */
-
- } /* if (socklen (Curproc->input,0) > 0) */
-
- /* Check async. */
-
- if (asy_len (dev) > 0)
- {
- c = get_asy (dev);
- break;
- }
-
- /* Let someone else run. */
-
- if (pwait (0) != 0)
- {
- c = -1;
- break;
- }
-
- } /* for (;;) */
-
- return (c);
- } /* static int asy_kb_poll (dev) */
-